package com.lizemin.spring.util;

/**
 * @author lzm
 * @date 2025/4/30 21:26
 * @description
 */

import cn.hutool.core.util.StrUtil;
import lombok.Getter;
import org.yaml.snakeyaml.Yaml;

import java.io.InputStream;
import java.util.Map;
import java.util.Properties;

public class YamlConfigLoader {

    @Getter
    private static Properties config;

    static {
        config = loadYamlConfig();
    }

    /**
     * 从 application.yml 文件加载配置到 Properties 集合
     * @return 包含配置信息的 Properties 集合
     */
    public static Properties loadYamlConfig() {
        Yaml yaml = new Yaml();
        // 从类路径下获取 application.yml 文件的输入流
        InputStream inputStream = YamlConfigLoader.class.getClassLoader().getResourceAsStream("application.yml");
        if (inputStream == null) {
            throw new RuntimeException("未找到 application.yml 文件");
        }
        // 解析 YAML 文件为 Map
        Map<String, Object> yamlMap = yaml.load(inputStream);
        Properties properties = new Properties();
        // 将嵌套的 Map 转换为扁平的键值对
        flattenMap(yamlMap, "", properties);
        return properties;
    }

    /**
     * 根据指定的键获取配置，并将结果转成目标类型
     * @param key 配置的键
     * @param targetClass 目标类型
     * @return 配置
     */
    public static <T> T getConfig(String key, Class<T> targetClass) {
        if (StrUtil.isBlank(key)) {
            throw new RuntimeException("配置键不能为空");
        }
        if (targetClass == null) {
            throw new RuntimeException("目标类型不能为空");
        }
        Object val = config.get(key);
        return ConvertionService.convert(val, targetClass);
    }

    /**
     * 将嵌套的 Map 转换为扁平的键值对，键使用点分隔
     * @param map 嵌套的 Map
     * @param parentKey 父键
     * @param properties 用于存储扁平键值对的 Properties 集合
     */
    @SuppressWarnings("unchecked")
    private static void flattenMap(Map<String, Object> map, String parentKey, Properties properties) {
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            String key = parentKey.isEmpty() ? entry.getKey() : parentKey + "." + entry.getKey();
            Object value = entry.getValue();
            if (value instanceof Map) {
                // 递归处理嵌套的 Map
                flattenMap((Map<String, Object>) value, key, properties);
            } else {
                properties.put(key, value);
            }
        }
    }

    public static void main(String[] args) {
        Properties properties = loadYamlConfig();
        // 打印所有配置项
        properties.forEach((key, value) -> System.out.println(key + " = " + value));
    }
}